#include "Logger.h"
#include <iomanip>
#include <iostream>
#include <sstream>

std::shared_ptr<spdlog::logger> Logger::logger = nullptr;
std::once_flag Logger::initFlag;
std::mutex Logger::mutex;

// 初始化日志系统
void Logger::init(const LoggerConfig& config) {
    std::call_once(initFlag, [&]() {
        std::lock_guard<std::mutex> lock(mutex);
		

        try {
            // 创建文件sink
            std::string fileName = generateTimestampedFileName(config.baseFileName);
            auto fileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
                fileName, config.maxFileSize, config.maxFiles);

            // 创建控制台sink
            std::vector<spdlog::sink_ptr> sinks;
            sinks.push_back(fileSink);

            if (config.consoleOutput) {
                auto consoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
                sinks.push_back(consoleSink);
            }

            // 创建多sink的logger
            logger = std::make_shared<spdlog::logger>("multi_sink_logger", sinks.begin(), sinks.end());

            // 设置日志格式
            logger->set_pattern("%Y-%m-%d %H:%M:%S.%e [%l] %v");

            // 设置日志级别
            logger->set_level(config.level);

            // 当达到或超过这个日志级别时，spdlog 会自动刷新日志缓冲区。
            logger->flush_on(spdlog::level::trace);

            // 注册日志器
            spdlog::register_logger(logger);

            LOG_INFO("Logger initialized successfully. File: {}", fileName);
        } catch (const spdlog::spdlog_ex& ex) {
            std::cerr << "Log initialization failed: " << ex.what() << std::endl;
        }
    });
}

// 清理资源
void Logger::cleanup() {
    std::lock_guard<std::mutex> lock(mutex);
    if (logger) {
        LOG_INFO("Logger cleaning up resources.");
        spdlog::drop(logger->name());
        logger.reset();
    }
}

// 获取日志器
std::shared_ptr<spdlog::logger> Logger::getLogger() {
    return logger;
}

// 设置日志级别
void Logger::setLevel(spdlog::level::level_enum level) {
    if (logger) {
        logger->set_level(level);
    }
}

// 提取文件名（不含路径）
std::string Logger::extractFileName(const std::string& filePath) {
    size_t lastSlash = filePath.find_last_of("/\\");
    if (lastSlash != std::string::npos) {
        return filePath.substr(lastSlash + 1);
    }
    return filePath;
}

// 生成带时间戳的文件名
std::string Logger::generateTimestampedFileName(const std::string& baseName) {
    auto now = std::chrono::system_clock::now();
    auto now_c = std::chrono::system_clock::to_time_t(now);
    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;

    std::tm* localTime = std::localtime(&now_c);

    std::ostringstream oss;
    oss << baseName
        << "_"
        << std::put_time(localTime, "%Y%m%d_%H%M%S")
        << "."
        << std::setfill('0') << std::setw(3) << now_ms.count()
        << ".log";

    return oss.str();
}
